/*
 * SpaceApp.cpp
 *
 *  Created on: 21 jan 2010
 *      Author: FIDD
 */

#include "SpaceApp.h"
#include <iostream>
#include <sstream>
#include <time.h>
#include <vector>
#include <string>

#include "engine/graphics/Sprite.h"
#include "engine/graphics/ScreenManager.h"
#include "engine/text/FontManager.h"
#include "engine/text/StringInput.h"
#include "engine/util/string_manip.h"
#include "engine/CollisionManager.h"
#include "engine/audio/AudioManager.h"

#include "single/Game.h"

#include "Bullet.h"
#include "SpaceClient.h"
#include "SpaceServer.h"
#include "SpaceMenu.h"

using namespace std;

SpaceApp::SpaceApp(int w, int h, int bpp, char *title)
	: SDLApp(w, h, bpp) {

	SDL_WM_SetCaption(title, NULL);
	before=SDL_GetTicks();
	follow = 0;
}

SpaceApp::~SpaceApp() {
}

void SpaceApp::init() {
	// Real random
	srand(time(0));

	Bullet::declareBulletTypes();
	menu = new SpaceMenu(this);
	sound = new AudioManager;
	sound->Addsound("gun1");

	float h= scrh/(float)1050;
	FontManager::loadFont("256BYTES.ttf", h*32, "256bytes");
	FontManager::loadFont("lucida.ttf", h*16, "lucida16");
	FontManager::loadFont("courier.ttf", h*16, "courier16");

	console = new Console("courier16", this);

	status = STATE_RUNNING;
	mode = MODE_MULTI;

	singleGame = new Single::Game();

	client = NULL;
	server = NULL;


	background = new Sprite("Maps/level1.png");
	background->moveTo(0, 0);
	ship = new Sprite("Sprites/explosion17.png");
	ship->loadAnimation(5,5,20);

	int keys[]={SDLK_UP,SDLK_LEFT,SDLK_DOWN,SDLK_RIGHT,SDLK_RCTRL};

	players.push_back(new Player(keys, Player::SHIP_RED));
	//players.push_back(new Player(keys2, Player::SHIP_BLUE));

	players[0]->moveTo(0,0);
	players[0]->setName("Player 1");

	/*players[1]->moveTo(1580,1050/2);
	players[1]->rotate(180);
	players[1]->setName("Player 2");

*/



	// Init SDL_net
	if (SDLNet_Init() < 0) {
		cout << "SDLNet_Init() failed" << endl;
	}

	//client = new SpaceClient("87.227.65.138", 2000, this);
	//server = new SpaceServer(2000, this);

	playerIndex= 0;



}

void SpaceApp::handleEvents(SDL_Event *e) {

	if (( e->type == SDL_KEYDOWN ) && ( e->key.keysym.sym == SDLK_ESCAPE ) ) {
		if (status == STATE_MENU) {
			quit = true;
		}
	}

	if (status == STATE_RUNNING) {
		if (( e->type == SDL_KEYDOWN ) && ( e->key.keysym.sym == SDLK_ESCAPE ) ) {
			status = STATE_MENU;
			SDL_ShowCursor(SDL_ENABLE);
		}

		if (mode == MODE_SINGLE) {
			singleGame->getCurrentLevel()->handleEvents(e);
		}
		else {
			if (e->type == SDL_KEYDOWN) {
				if( e->key.keysym.sym == SDLK_SPACE ) {
					follow = (follow+1)% players.size();
				}
			}
		}
	}
	else if (status == STATE_MENU) {
		menu->userInput(e);
	}

	console->handleInput(e);

}

void SpaceApp::handleInput() {

	Uint8 *keys = SDL_GetKeyState( NULL );
	if (mode == MODE_SINGLE) {
		singleGame->getCurrentLevel()->userInput(keys);
	}
	else {
		if (status == STATE_RUNNING) {

			players[playerIndex]->setKeysDown(keys);
		}
		else if (status == STATE_CONSOLE) {
			players[playerIndex]->resetKeys();
		}
	}

}

void SpaceApp::update(int elapsed) {

	if (client != NULL) {
		client->update(elapsed);
	}
	if (server != NULL) {
		server->update(elapsed);
	}

	if (mode == MODE_SINGLE) {
		singleGame->getCurrentLevel()->update(elapsed);
	}
	else {
		ScreenManager::setCamera(players[follow]->getXpos(), players[follow]->getYpos());

		ship->getAnimation()->update(elapsed);
		ship->rotate(1.0);
		for(unsigned int i=0;i<players.size();i++){
			players[i]->updatePos(elapsed);
		}
		ship->move(0.5,0.5);

		if (CollisionManager::pixelCollision( background->getSurface(),
				players[playerIndex]->getXpos(),
				players[playerIndex]->getYpos())) {

			players[playerIndex]->moveTo(100, 100);
		}

		for (int i=0; i<players.size(); i++) {
			vector<Bullet*> blist = players[i]->getBullets();

			for (int j=0; j<players[i]->getBullets().size(); j++) {
				if (CollisionManager::pixelCollision( background->getSurface(),
						blist[j]->getXpos(),
						blist[j]->getYpos())) {

					players[i]->removeBullet(j);
				}
			}

			for (int p=0; p<players.size(); p++) {
				if (i!=p) {
					for (int j=0; j<players[i]->getBullets().size(); j++) {


						if ( CollisionManager::circleCollision( players[p]->getXpos(),
									players[p]->getYpos(),
									20,
									blist[j]->getXpos(),
									blist[j]->getYpos(),
									5) ) {

								//cout << "fire hit " << j << endl;
								players[i]->removeBullet(j);
								players[i]->moveTo(100, 100);
						}
					}
				}
			}


		}
	}
}

vector<string> SpaceApp::messages;
vector<Player*> SpaceApp::players;
void SpaceApp::draw() {

	glClear( GL_COLOR_BUFFER_BIT );

	if (status == STATE_MENU) {
		menu->draw();
	}
	else {

		if (mode == MODE_SINGLE) {
			singleGame->getCurrentLevel()->drawScene();
		}

		else {
			background->draw();

			for (unsigned int i=0; i<players.size(); i++){
				players[i]->draw();

				FontManager::drawText(players[i]->getName(), (int)ScreenManager::screenXpos((players[i]->getXpos()-50)),
							(int)ScreenManager::screenYpos((players[i]->getYpos()-50)), "256bytes");
			}
		}

		stringstream fpsString;
		fpsString << "FPS: " << fps;
		FontManager::drawText(fpsString.str(), 50, 50, "256bytes");


		// Print all messages
		if (status == STATE_CONSOLE){

			console->draw();
			glColor4f(1, 1, 1, .7);
			for (unsigned int i=messages.size(); i>0; i--) {
				FontManager::drawText(messages[i-1], 50, 300-20*(messages.size()-i), "courier16");
			}
			glColor4f(1, 1, 1, 1);
		}
	}

	SDL_GL_SwapBuffers();

	int ticks=SDL_GetTicks();


	if((ticks-before)>=100){
		before=SDL_GetTicks();
	}
	if(((ticks-before)%10)==0){
		SDL_Delay(10);
	}else{
		SDL_Delay(10-((ticks-before)%10));
	}


	/*if (10-(ticks-before)<1) {
		SDL_Delay(0);
	} else {
		SDL_Delay(10-(ticks-before));
	}*/

	before=SDL_GetTicks();
}

void SpaceApp::dostring(string str) {

	vector<string> res = split(str, " ");
	if (res[0] == "connect") {
		if (client == NULL) {
			client = new SpaceClient(res[1], 2000, this);
		}
		print("Connect to " + res[1], 0, 0);
	}

	else if (res[0] == "host") {
		if (server == NULL) {
			server = new SpaceServer(2000, this);
		}
		print("Host", 0, 0);
	}
	else{
		print(str,0,0);
	}

}

void SpaceApp::print(string msg, int x, int y) {
	messages.push_back(msg);
	cout << msg << endl;
}

void SpaceApp::addPlayer(Player *p) {
	players.push_back(p);
	cout << "Player added to vector: " << players.size() << "\n";

	int num = players.size();
	stringstream name;
	name << "Player " << num;
	p->setName(name.str());
}

